package com.janlei.acc.single;

import java.util.Objects;

/**
 * 单例模式
 */
public class SingleStu {

    //1.私有构造器
    private SingleStu() {
    }

    //2.通过提供对外返回实例的静态方法
    public static SingleStu getInstance() {
        return instance;
    }

    //注意是否存在线程安全
    //是否启用懒加载
    private static final SingleStu instance = new SingleStu();
    //使用final对对象做缓存，final缓存不可变实例
}

/**
 * 单例双重检查锁实现
 */
class SingleDoubleCheck {

    private static SingleDoubleCheck singleDoubleCheck;

    private SingleDoubleCheck() {
    }

    public static SingleDoubleCheck getInstance() {
        if (Objects.isNull(singleDoubleCheck)) {
            synchronized (SingleDoubleCheck.class) {
                if (Objects.isNull(singleDoubleCheck)) {
                    singleDoubleCheck = new SingleDoubleCheck();
                }
            }
        }
        return singleDoubleCheck;
    }
}

/**
 * 静态内部类实现单例
 */
class SingleStaticClass {

    private String key;
    private String value;

    private SingleStaticClass() {
    }

    private SingleStaticClass(String key, String value) {
        this.key = key;
        this.value = value;
    }

    /**
     * 内部类调用父类私有构造器
     */
    private static class InnerClass {
        private static final SingleStaticClass INSTANCE = new SingleStaticClass("key", "value");
    }

    public static SingleStaticClass getInstance() {
        return InnerClass.INSTANCE;
    }

    @Override
    public String toString() {
        return "SingleStaticClass{" +
                "key='" + key + '\'' +
                ", value='" + value + '\'' +
                '}';
    }
}

/**
 * 枚举单例 避免反序列化
 */
enum SingleEnum {
    INSTANCE {
        public String getType() {
            System.out.println("init");
            long s = System.currentTimeMillis();
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            long e = System.currentTimeMillis();
            System.out.println("load time:" + (e - s));
            return "Spring";
        }
    };

    public SingleEnum getInstance() {
        return INSTANCE;
    }

    /**
     * 获取枚举属性值
     */
    private String type;

    public String getType() {
        return type;
    }

}